package RiverCrossingMinigame;

// Some code was adapted from the Virginia CS homework assignments and 
// tutorials/examples/explanations found here http://www.cs.virginia.edu/cs201j/problem-sets/ps5/

/**
 * This class represents a lane in which floating objects can move across the grid
 * The lane also groups these objects together for the purposes of multithreading. 
 * 
 * @author Ray DeCuir
 * @version 1.0
 *
 */

public class Lane implements Runnable{
	
	// The grid to which the lanes belong
	Grid grid;
	
	// the position of the lane on the grid
	int laneNum;
	
	// the thread used to run the lane
	Thread t;

	/**
	 * Constructor that creates the lane and sets it up on the grid 
	 * 
	 * @param g The gird to which the lane will be added
	 * @param n The position of the lane in the grid
	 */
	public Lane (Grid g, int n){
		grid = g;
		laneNum = n;
		
		// customize the lane based on the lane number 
		if (laneNum==2 ){
			try
			{
				FloatingPiece log1p1 = new FloatingPiece(-1);
				FloatingPiece log1p2 = new FloatingPiece(-1);
				FloatingPiece log1p3 = new FloatingPiece(-1);
				FloatingPiece log2p1 = new FloatingPiece(-1);
				FloatingPiece log2p2 = new FloatingPiece(-1);
				FloatingPiece log2p3 = new FloatingPiece(-1);

				// make a length 5 log
				grid.setObjectAt(5, laneNum, log1p1);
				log1p1.init(5, laneNum, grid);
				grid.setObjectAt(7, laneNum, log1p2);
				log1p2.init(7, laneNum, grid);
				grid.setObjectAt(9, laneNum, log1p3);
				log1p3.init(9, laneNum, grid);

				// make another length 5 log
				grid.setObjectAt(13, laneNum, log2p1);
				log2p1.init(13, laneNum, grid);
				grid.setObjectAt(15, laneNum, log2p2);
				log2p2.init(15, laneNum, grid);
				grid.setObjectAt(17, laneNum, log2p3);
				log2p3.init(17, laneNum, grid);

				// make a new thread to handle this lane
				t  = new Thread(this);
				t.start();
			}
			catch(Exception e) { }
		}
		else if (laneNum==3 ){
			try
			{
				FloatingPiece log1p1 = new FloatingPiece(1);
				FloatingPiece log1p2 = new FloatingPiece(1);
				FloatingPiece log1p3 = new FloatingPiece(1);
				FloatingPiece log2p2 = new FloatingPiece(1);
				FloatingPiece log2p3 = new FloatingPiece(1);

				// make a length 5 log
				grid.setObjectAt(5, laneNum, log1p1);
				log1p1.init(5, laneNum, grid);
				grid.setObjectAt(7, laneNum, log1p2);
				log1p2.init(7, laneNum, grid);
				grid.setObjectAt(9, laneNum, log1p3);
				log1p3.init(9, laneNum, grid);

				// make a length 3 log
				grid.setObjectAt(15, laneNum, log2p2);
				log2p2.init(15, laneNum, grid);
				grid.setObjectAt(17, laneNum, log2p3);
				log2p3.init(17, laneNum, grid);

				// make a new thread to handle this lane
				t  = new Thread(this);
				t.start();

			}
			catch(Exception e) { }			

		}
		else if (laneNum==4 ){
			try
			{
				FloatingPiece log1p1 = new FloatingPiece(-1);
				FloatingPiece log1p2 = new FloatingPiece(-1);
				FloatingPiece log2p1 = new FloatingPiece(-1);
				FloatingPiece log2p2 = new FloatingPiece(-1);

				// make a length 3 log
				grid.setObjectAt(3, laneNum, log1p1);
				log1p1.init(3, laneNum, grid);
				grid.setObjectAt(5, laneNum, log1p2);
				log1p2.init(5, laneNum, grid);

				// make another length 3 log
				grid.setObjectAt(12, laneNum, log2p1);
				log2p1.init(12, laneNum, grid);
				grid.setObjectAt(14, laneNum, log2p2);
				log2p2.init(14, laneNum, grid);

				// make a new thread to handle this lane
				t  = new Thread(this);
				t.start();
			}
			catch (Exception e){}			

		}
		else if (laneNum==5 ){
			try
			{
				FloatingPiece log1p1 = new FloatingPiece(1);
				FloatingPiece log1p2 = new FloatingPiece(1);
				FloatingPiece log1p3 = new FloatingPiece(1);
				FloatingPiece log2p1 = new FloatingPiece(1);
				FloatingPiece log3p1 = new FloatingPiece(1);
				FloatingPiece log4p1 = new FloatingPiece(1);

				// make a length 5 log
				grid.setObjectAt(5, laneNum, log1p1);
				log1p1.init(5, laneNum, grid);
				grid.setObjectAt(7, laneNum, log1p2);
				log1p2.init(7, laneNum, grid);
				grid.setObjectAt(9, laneNum, log1p3);
				log1p3.init(9, laneNum, grid);

				// make length 1 logs
				grid.setObjectAt(13, laneNum, log2p1);
				log2p1.init(13, laneNum, grid);
				grid.setObjectAt(18, laneNum, log3p1);
				log3p1.init(18, laneNum, grid);
				grid.setObjectAt(1, laneNum, log4p1);
				log4p1.init(1, laneNum, grid);

				// make a new thread to handle this lane
				t  = new Thread(this);
				t.start();
			}
			catch(Exception e) { }			

		}
		else if (laneNum==6 ){
			try
			{
				FloatingPiece log1p1 = new FloatingPiece(-1);
				FloatingPiece log1p2 = new FloatingPiece(-1);
				FloatingPiece log2p1 = new FloatingPiece(-1);
				FloatingPiece log3p1 = new FloatingPiece(-1);
				FloatingPiece log4p1 = new FloatingPiece(-1);

				// make a length 3 log
				grid.setObjectAt(14, laneNum, log1p1);
				log1p1.init(14, laneNum, grid);
				grid.setObjectAt(16, laneNum, log1p2);
				log1p2.init(16, laneNum, grid);

				// make length 1 logs
				grid.setObjectAt(1, laneNum, log2p1);
				log2p1.init(1, laneNum, grid);
				grid.setObjectAt(5, laneNum, log3p1);
				log3p1.init(5, laneNum, grid);
				grid.setObjectAt(1, laneNum, log4p1);
				log4p1.init(1, laneNum, grid);

				// make a new thread to handle this lane
				t  = new Thread(this);
				t.start();
			}
			catch (Exception e){}			

		}
	}

	
	/**
	 * Moves all of the objects in the lane continuously while the player is playing the game. 
	 * 
	 */
	public void run()
	{
		Movable space;
		while (true) 
		{
			synchronized(this) 
			{
				for (int j = 0; j < 20; j++)
				{
					space = grid.getObjectAt(j, laneNum);
					if(space != null)
					{
						if(space instanceof Vehicle)
							continue;
						space.executeTurn();
						j++;
						try
						{
							Thread.sleep( (1) );
						}
						catch(Exception e) {
							e.printStackTrace(); 
						}
					}
				}
				try
				{
					Thread.sleep( (80 * laneNum) );
				}
				catch(Exception e) { 
					e.printStackTrace(); 
				}
			}
		}
	}
}